<!DOCTYPE html>
<html>

<head>
  <title>Quarkus - Using the Cassandra Client</title>
  <script id="adobe_dtm" src="https://www.redhat.com/dtm.js" type="text/javascript"></script>
  <script src="/assets/javascript/highlight.pack.js" type="text/javascript"></script>
  <META HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'none'; script-src 'self' 'unsafe-eval' 'sha256-ANpuoVzuSex6VhqpYgsG25OHWVA1I+F6aGU04LoI+5s=' 'sha256-ipy9P/3rZZW06mTLAR0EnXvxSNcnfSDPLDuh3kzbB1w=' js.bizographics.com https://www.redhat.com assets.adobedtm.com jsonip.com https://ajax.googleapis.com https://www.googletagmanager.com https://www.google-analytics.com https://use.fontawesome.com; style-src 'self' https://fonts.googleapis.com https://use.fontawesome.com; img-src 'self' *; media-src 'self' ; frame-src https://www.googletagmanager.com https://www.youtube.com; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; font-src 'self' https://use.fontawesome.com https://fonts.gstatic.com;">
  <META HTTP-EQUIV='X-Frame-Options' CONTENT="DENY">
  <META HTTP-EQUIV='X-XSS-Protection' CONTENT="1; mode=block">
  <META HTTP-EQUIV='X-Content-Type-Options' CONTENT="nosniff">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Quarkus: Supersonic Subatomic Java">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@QuarkusIO"> 
  <meta name="twitter:creator" content="@QuarkusIO">
  <meta property="og:url" content="https://quarkus.io/guides/cassandra" />
  <meta property="og:title" content="Quarkus - Using the Cassandra Client" />
  <meta property="og:description" content="Quarkus: Supersonic Subatomic Java" />
  <meta property="og:image" content="/assets/images/quarkus_card.png" />
  <link rel="canonical" href="https://quarkus.io/guides/cassandra">
  <link rel="shortcut icon" type="image/png" href="/favicon.ico" >
  <link rel="stylesheet" href="https://quarkus.io/guides/stylesheet/config.css" />
  <link rel="stylesheet" href="/assets/css/main.css" />
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
  <link rel="alternate" type="application/rss+xml"  href="https://quarkus.io/feed.xml" title="Quarkus">
  <script src="https://quarkus.io/assets/javascript/goan.js" type="text/javascript"></script>
  <script src="https://quarkus.io/assets/javascript/hl.js" type="text/javascript"></script>
</head>

<body class="guides">
  <!-- Google Tag Manager (noscript) -->
  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJWS5L"
  height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->

  <div class="nav-wrapper">
  <div class="grid-wrapper">
    <div class="width-12-12">
      <input type="checkbox" id="checkbox" />
      <nav id="main-nav" class="main-nav">
  <div class="container">
    <div class="logo-wrapper">
      
        <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_600px_reverse.png" class="project-logo" title="Quarkus"></a>
      
    </div>
    <label class="nav-toggle" for="checkbox">
      <i class="fa fa-bars"></i>
    </label>
    <div id="menu" class="menu">
      <span>
        <a href="/get-started/" class="">Get Started</a>
      </span>
      <span>
        <a href="/guides/" class="active">Guides</a>
      </span>
      <span>
        <a href="/community/" class="">Community</a>
      </span>
      <span>
        <a href="/support/" class="">Support</a>
      </span>
      <span>
        <a href="/blog/" class="">Blog</a>
      </span>
      <span>
        <a href="https://code.quarkus.io" class="button-cta secondary white">Start Coding</a>
      </span>
    </div>
  </div>
      </nav>
    </div>
  </div>
</div>

  <div class="content">
    <div class="guide">
  <div class="width-12-12">
    <h1 class="text-caps">Quarkus - Using the Cassandra Client</h1>
    <div class="hide-mobile toc"><ul class="sectlevel1">
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#architecture">Architecture</a></li>
<li><a href="#solution">Solution</a></li>
<li><a href="#creating-the-maven-project">Creating the Maven project</a></li>
<li><a href="#creating-json-rest-service">Creating JSON REST service</a></li>
<li><a href="#configuring-the-cassandra-database">Configuring the Cassandra database</a>
<ul class="sectlevel2">
<li><a href="#connecting-to-apache-cassandra-or-datastax-enterprise-dse">Connecting to Apache Cassandra or DataStax Enterprise (DSE)</a></li>
<li><a href="#connecting-to-a-cloud-datastax-astra-database">Connecting to a cloud DataStax Astra database</a></li>
<li><a href="#advanced-driver-configuration">Advanced driver configuration</a></li>
</ul>
</li>
<li><a href="#running-a-cassandra-database">Running a Cassandra Database</a></li>
<li><a href="#creating-a-frontend">Creating a frontend</a></li>
<li><a href="#reactive">Reactive Cassandra Client</a></li>
<li><a href="#creating-a-reactive-frontend">Creating a reactive frontend</a></li>
<li><a href="#connection-health-check">Connection Health Check</a></li>
<li><a href="#metrics">Metrics</a></li>
<li><a href="#building-a-native-executable">Building a native executable</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul></div>
    <div>
      <div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Apache Cassandra® is a free and open-source, distributed, wide column store, NoSQL database
management system designed to handle large amounts of data across many commodity servers, providing
high availability with no single point of failure.</p>
</div>
<div class="paragraph">
<p>In this guide, we will see how you can get your REST services to use a Cassandra database.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>This extension is developed by a third party and is part of the Quarkus Platform.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="prerequisites"><a class="anchor" href="#prerequisites"></a>Prerequisites</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To complete this guide, you need:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>an IDE</p>
</li>
<li>
<p>JDK 1.8+ installed with <code>JAVA_HOME</code> configured appropriately</p>
</li>
<li>
<p>GraalVM installed with <code>GRAALVM_HOME</code> configured appropriately if you want to use the native mode.</p>
</li>
<li>
<p>Apache Maven 3.6.2+</p>
</li>
<li>
<p>Cassandra or Docker installed</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="architecture"><a class="anchor" href="#architecture"></a>Architecture</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The application built in this guide is quite simple: the user can add elements in a list using a
form, and the items list is updated.</p>
</div>
<div class="paragraph">
<p>All the information between the browser and the server is formatted as JSON.</p>
</div>
<div class="paragraph">
<p>The elements are stored in the Cassandra database.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="solution"><a class="anchor" href="#solution"></a>Solution</h2>
<div class="sectionbody">
<div class="paragraph">
<p>We recommend that you follow the instructions in the next sections and create the application step
by step.
However, you can go right to the completed example.</p>
</div>
<div class="paragraph">
<p>The solution is located in the <code>quickstart</code>
<a href="https://github.com/datastax/cassandra-quarkus/tree/master/quickstart">directory</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="creating-the-maven-project"><a class="anchor" href="#creating-the-maven-project"></a>Creating the Maven project</h2>
<div class="sectionbody">
<div class="paragraph">
<p>First, create a new Maven project and copy the <code>pom.xml</code> file that is present in the <code>quickstart</code>
directory.</p>
</div>
<div class="paragraph">
<p>The <code>pom.xml</code> is importing the RESTEasy/JAX-RS, JSON-B, Context Propagation and Cassandra Client
extensions.</p>
</div>
<div class="paragraph">
<p>We will be building a REST application using the
<a href="https://docs.datastax.com/en/developer/java-driver/latest/manual/mapper">DataStax Object Mapper</a>
to simplify the Data Access Layer code.</p>
</div>
<div class="paragraph">
<p>The most important part of the <code>pom.xml</code> is adding the <code>cassandra-quarkus</code> extension:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
    &lt;groupId&gt;com.datastax.oss.quarkus&lt;/groupId&gt;
    &lt;artifactId&gt;cassandra-quarkus-client&lt;/artifactId&gt;
    &lt;version&gt;${quarkus.version}&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="creating-json-rest-service"><a class="anchor" href="#creating-json-rest-service"></a>Creating JSON REST service</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In this example, we will create an application to manage a list of fruits.</p>
</div>
<div class="paragraph">
<p>First, let&#8217;s create the <code>Fruit</code> bean as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@Entity
public class Fruit {

    @PartitionKey private String storeId;
    @ClusteringColumn private String name;
    private String description;

    public Fruit() {}

    public Fruit(String storeId, String name, String description) {
      this.storeId = storeId;
      this.name = name;
      this.description = description;
    }

    // getters, setters, hashCode and equals omitted for brevity
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>We are using DataStax Java driver Object Mapper, which is why this class is annotated with an
<code>@Entity</code>. Also, the <code>storeId</code> field represents a Cassandra partition key and <code>name</code> represents a
clustering column, and so we are using the corresponding annotations from the Object Mapper library.
It will allow the Mapper to generate proper CQL queries underneath.</p>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
Entity classes are required to have a default no-args constructor.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>To leverage the Mapper logic in this app we need to create a DAO:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@Dao
public interface FruitDao {
  @Update
  void update(Fruit fruit);

  @Select
  PagingIterable&lt;Fruit&gt; findById(String id);
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This class exposes operations that will be used in the REST service.</p>
</div>
<div class="paragraph">
<p>Finally, the Mapper itself:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@Mapper
public interface FruitMapper {
  @DaoFactory
  FruitDao fruitDao();
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The mapper is responsible for constructing instances of <code>FruitDao</code>. In the example above, the
<code>FruitDao</code> instance will be connected to the same keyspace as the underlying session. More on that
below.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
It is also possible to create DAO instances for different keyspaces. To learn how, see
<a href="https://docs.datastax.com/en/developer/java-driver/4.7/manual/mapper/mapper/#dao-parameterization">DAO parameterization</a>
in the driver docs.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Next, we need a component to create our DAO instances: <code>FruitDaoProducer</code>. Indeed, Mapper and Dao
instances are stateful objects, and should be created only once, as application-scoped singletons.
This component will do exactly that, leveraging Quarkus Dependency Injection container:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">import com.datastax.oss.driver.api.core.CqlIdentifier;
import com.datastax.oss.quarkus.runtime.api.config.CassandraClientConfig;
import com.datastax.oss.quarkus.runtime.api.session.QuarkusCqlSession;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import javax.inject.Inject;

public class FruitDaoProducer {

  private final FruitDao fruitDao;
  private final FruitDaoReactive fruitDaoReactive;

  @Inject
  public FruitDaoProducer(QuarkusCqlSession session) {
    // create a mapper
    FruitMapper mapper = new FruitMapperBuilder(session).build();
    // instantiate our Daos
    fruitDao = mapper.fruitDao();
    fruitDaoReactive = mapper.fruitDaoReactive();
  }

  @Produces
  @ApplicationScoped
  FruitDao produceFruitDao() {
    return fruitDao;
  }

  @Produces
  @ApplicationScoped
  FruitDaoReactive produceFruitDaoReactive() {
    return fruitDaoReactive;
  }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Note how the <code>QuarkusCqlSession</code> instance is injected automatically by the cassandra-quarkus
extension in the <code>FruitDaoProducer</code> constructor.</p>
</div>
<div class="paragraph">
<p>Now create a <code>FruitService</code> that will be the business layer of our application and store/load the
fruits from the Cassandra database.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@ApplicationScoped
public class FruitService {

  private final FruitDao dao;

  @Inject
  public FruitService(FruitDao dao) {
    this.dao = dao;
  }

  public void save(Fruit fruit) {
    dao.update(fruit);
  }

  public List&lt;Fruit&gt; get(String id) {
    return dao.findById(id).all();
  }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Note how the service receives a <code>FruitDao</code> instance in the constructor. This DAO instance is
provided by <code>FruitDaoProducer</code> and injected automatically.</p>
</div>
<div class="paragraph">
<p>The last missing piece is the REST API that will expose GET and POST methods:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@Path("/fruits")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class FruitResource {

  private static final String STORE_NAME = "acme";

  @Inject FruitService fruitService;

  @GET
  public List&lt;FruitDto&gt; list() {
    return fruitService.get(STORE_NAME).stream()
        .map(fruit -&gt; new FruitDto(fruit.getName(), fruit.getDescription()))
        .collect(Collectors.toList());
  }

  @POST
  public void add(FruitDto fruit) {
    fruitService.save(covertFromDto(fruit));
  }

  private Fruit covertFromDto(FruitDto fruitDto) {
    return new Fruit(fruitDto.getName(), fruitDto.getDescription(), STORE_NAME);
  }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>list</code> and <code>add</code> operations are executed for the <code>storeId</code> "acme". This is the partition key of
our data model. We can easily retrieve all rows from cassandra using that partition key.
They will be sorted by the clustering column. <code>FruitResource</code> is using <code>FruitService</code> which
encapsulates the data access logic.</p>
</div>
<div class="paragraph">
<p>When creating the REST API we should not share the same entity object between REST API and data
access layers. They should not be coupled to allow the API to evolve independently of the storage
layer. This is the reason why the API is using a <code>FruitDto</code> class. This class will be used by
Quarkus to convert JSON to java objects for client requests and java objects to JSON for the
responses. The translation is done by quarkus-resteasy extension.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">public class FruitDto {

  private String name;
  private String description;

  public FruitDto() {}

  public FruitDto(String name, String description) {
    this.name = name;
    this.description = description;
  }
  // getters and setters omitted for brevity
}</code></pre>
</div>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
DTO classes used by the JSON serialization layer are required to have a default no-arg
constructor.
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="configuring-the-cassandra-database"><a class="anchor" href="#configuring-the-cassandra-database"></a>Configuring the Cassandra database</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="connecting-to-apache-cassandra-or-datastax-enterprise-dse"><a class="anchor" href="#connecting-to-apache-cassandra-or-datastax-enterprise-dse"></a>Connecting to Apache Cassandra or DataStax Enterprise (DSE)</h3>
<div class="paragraph">
<p>The main properties to configure are: <code>contact-points</code>, to access the Cassandra database,
<code>local-datacenter</code>, which is required by the driver, and – optionally – the keyspace to bind to.</p>
</div>
<div class="paragraph">
<p>A sample configuration should look like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="properties" class="language-properties hljs">quarkus.cassandra.contact-points={cassandra_ip}:9042
quarkus.cassandra.local-datacenter={dc_name}
quarkus.cassandra.keyspace={keyspace}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this example, we are using a single instance running on localhost, and the keyspace containing
our data is <code>k1</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="properties" class="language-properties hljs">quarkus.cassandra.contact-points=127.0.0.1:9042
quarkus.cassandra.local-datacenter=datacenter1
quarkus.cassandra.keyspace=k1</code></pre>
</div>
</div>
<div class="paragraph">
<p>If your cluster requires plain text authentication, you can also provide two more settings:
<code>username</code> and <code>password</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="properties" class="language-properties hljs">quarkus.cassandra.auth.username=john
quarkus.cassandra.auth.password=s3cr3t</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="connecting-to-a-cloud-datastax-astra-database"><a class="anchor" href="#connecting-to-a-cloud-datastax-astra-database"></a>Connecting to a cloud DataStax Astra database</h3>
<div class="paragraph">
<p>When connecting to Astra, instead of providing a contact point and a datacenter, you should provide
<code>secure-connect-bundle</code>, which should point to a valid path to an Astra secure connect bundle, as
well as <code>username</code> and`password`, since authentication is always required on Astra clusters.</p>
</div>
<div class="paragraph">
<p>A sample configuration for DataStax Astra should look like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="properties" class="language-properties hljs">quarkus.cassandra.cloud.secure-connect-bundle=/path/to/secure-connect-bundle.zip
quarkus.cassandra.auth.username=john
quarkus.cassandra.auth.password=s3cr3t
quarkus.cassandra.keyspace=k1</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="advanced-driver-configuration"><a class="anchor" href="#advanced-driver-configuration"></a>Advanced driver configuration</h3>
<div class="paragraph">
<p>You can configure other Java driver settings using <code>application.conf</code> or <code>application.json</code> files.
They need to be located in the classpath of your application.
All settings will be passed automatically to the underlying driver configuration mechanism.
Settings defined in <code>application.properties</code> with the <code>quarkus.cassandra</code> prefix will have priority
over settings defined in <code>application.conf</code> or <code>application.json</code>.</p>
</div>
<div class="paragraph">
<p>To see the full list of settings, please refer to the
<a href="https://docs.datastax.com/en/developer/java-driver/latest/manual/core/configuration/reference/">driver settings reference</a>.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="running-a-cassandra-database"><a class="anchor" href="#running-a-cassandra-database"></a>Running a Cassandra Database</h2>
<div class="sectionbody">
<div class="paragraph">
<p>By default, <code>CassandraClient</code> is configured to access a local Cassandra database on port 9042 (the
default Cassandra port).</p>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
Make sure that the setting <code>quarkus.cassandra.local-datacenter</code>
matches the datacenter of your Cassandra cluster.
</td>
</tr>
</table>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
If you don&#8217;t know the name of your local datacenter, this value can be found by running the
following CQL query: <code>SELECT data_center FROM system.local</code>.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>If you want to use Docker to run a Cassandra database, you can use the following command to launch
one:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">docker run \
   --name local-cassandra-instance \
   -p 7000:7000 \
   -p 7001:7001 \
   -p 7199:7199 \
   -p 9042:9042 \
   -p 9160:9160 \
   -p 9404:9404 \
   -d \
   launcher.gcr.io/google/cassandra3</code></pre>
</div>
</div>
<div class="paragraph">
<p>Note that only the 9042 port is required. All others all optional but provide enhanced features
like JMX monitoring of the Cassandra instance.</p>
</div>
<div class="paragraph">
<p>Next you need to create the keyspace and table that will be used by your application. If you are
using Docker, run the following commands:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">docker exec -it local-cassandra-instance cqlsh -e "CREATE KEYSPACE IF NOT EXISTS k1 WITH replication = {'class':'SimpleStrategy', 'replication_factor':1}"
docker exec -it local-cassandra-instance cqlsh -e "CREATE TABLE IF NOT EXISTS k1.fruit(id text, name text, description text, PRIMARY KEY((id), name))"</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you&#8217;re running Cassandra locally you can execute the cqlsh commands directly:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">cqlsh -e "CREATE KEYSPACE IF NOT EXISTS k1 WITH replication = {'class':'SimpleStrategy', 'replication_factor':1}
cqlsh -e "CREATE TABLE IF NOT EXISTS k1.fruit(id text, name text, description text, PRIMARY KEY((id), name))</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="creating-a-frontend"><a class="anchor" href="#creating-a-frontend"></a>Creating a frontend</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Now let&#8217;s add a simple web page to interact with our <code>FruitResource</code>.</p>
</div>
<div class="paragraph">
<p>Quarkus automatically serves static resources located under the <code>META-INF/resources</code> directory.
In the <code>src/main/resources/META-INF/resources</code> directory, add a <code>fruits.html</code> file with the content
from this <a href="https://github.com/datastax/cassandra-quarkus/tree/master/quickstart/src/main/resources/META-INF/resources/fruits.html">fruits.html</a> file in it.</p>
</div>
<div class="paragraph">
<p>You can now interact with your REST service:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>start Quarkus with <code>mvn clean quarkus:dev</code></p>
</li>
<li>
<p>open a browser to <code><a href="http://localhost:8080/fruits.html" class="bare">http://localhost:8080/fruits.html</a></code></p>
</li>
<li>
<p>add new fruits to the list via the form</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="reactive"><a class="anchor" href="#reactive"></a>Reactive Cassandra Client</h2>
<div class="sectionbody">
<div class="paragraph">
<p>When using <code>QuarkusCqlSession</code> you have access to reactive variant of methods that integrate with
Quarkus and Mutiny.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
If you&#8217;re not familiar with Mutiny, read the
<a href="https://quarkus.io/guides/getting-started-reactive">Getting Started with Reactive guide</a> first.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Let&#8217;s rewrite the previous example using reactive programming with Mutiny.</p>
</div>
<div class="paragraph">
<p>Firstly, we need to implement the <code>@Dao</code> that works in a reactive way:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@Dao
public interface FruitDaoReactive {

  @Update
  Uni&lt;Void&gt; updateAsync(Fruit fruitDao);

  @Select
  MutinyMappedReactiveResultSet&lt;Fruit&gt; findByIdAsync(String id);
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Please note the usage of <code>MutinyMappedReactiveResultSet</code> - it is a specialized <code>Mutiny</code> type
converted from the original <code>Publisher</code> returned by the driver, which also exposes a few extra
methods, e.g. to obtain the query execution info. If you don&#8217;t need anything in that interface,
you can also simply declare your method to return <code>Multi</code>: <code>Multi&lt;Fruit&gt; findByIdAsync(String id)</code>,</p>
</div>
<div class="paragraph">
<p>Similarly, the method <code>updateAsync</code> returns a <code>Uni</code> - it is automatically converted from the
original result set returned by the driver.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The Cassandra driver uses the Reactive Streams <code>Publisher</code> API for reactive calls. The Quarkus
framework however uses Mutiny. Because of that, the <code>CqlQuarkusSession</code> interface transparently
converts the <code>Publisher</code> instances returned by the driver into the reactive type <code>Multi</code>.
<code>CqlQuarkusSession</code> is also capable of converting a <code>Publisher</code> into a <code>Uni</code> – in this case, the
publisher is expected to emit at most one row, then complete. This is suitable for write queries
(they return no rows), or for read queries guaranteed to return one row at most (count queries, for
example).
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Next, we need to adapt the <code>FruitMapper</code> to construct a <code>FruitDaoReactive</code> instance:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@Mapper
public interface FruitMapper {
  // the existing method omitted

  @DaoFactory
  FruitDaoReactive fruitDaoReactive();
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now, we can create a <code>FruitReactiveService</code> that leverages the reactive <code>@Dao</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@ApplicationScoped
public class FruitReactiveService {

  private final FruitDaoReactive fruitDao;

  @Inject
  public FruitReactiveService(FruitDaoReactive fruitDao) {
    this.fruitDao = fruitDao;
  }

  public Uni&lt;Void&gt; add(Fruit fruit) {
    return fruitDao.update(fruit);
  }

  public Multi&lt;Fruit&gt; get(String id) {
    return fruitDao.findById(id);
  }
}</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The <code>get()</code> method above returns <code>Multi</code>, and the <code>add()</code> method returns <code>Uni</code>; these types
are compatible with the Quarkus reactive REST API.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>To integrate the reactive logic with REST API, you need to have a dependency to
<code>quarkus-resteasy-mutiny</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
  &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
  &lt;artifactId&gt;quarkus-resteasy-mutiny&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>It provides an integration layer between <code>Multi</code>, <code>Uni</code> and the REST API.</p>
</div>
<div class="paragraph">
<p>Finally, we can create a <code>FruitReactiveResource</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@Path("/reactive-fruits")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class FruitReactiveResource {
  private static final String STORE_NAME = "acme";
  @Inject FruitReactiveService service;

  @GET
  public Multi&lt;FruitDto&gt; getAll() {
    return service
        .get(STORE_NAME)
        .map(fruit -&gt; new FruitDto(fruit.getName(), fruit.getDescription()));
  }

  @POST
  public Multi&lt;FruitDto&gt; add(FruitDto fruitDto) {
    Fruit fruit = covertFromDto(fruitDto);
    return service.add(fruit).then(ignored -&gt; getAll());
  }

  private Fruit covertFromDto(FruitDto fruitDto) {
    return new Fruit(fruitDto.getName(), fruitDto.getDescription(), STORE_NAME);
  }
}</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
All methods exposed via REST interface are returning reactive types from the Mutiny API.
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="creating-a-reactive-frontend"><a class="anchor" href="#creating-a-reactive-frontend"></a>Creating a reactive frontend</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Now let&#8217;s add a simple web page to interact with our <code>FruitReactiveResource</code>.
In the <code>src/main/resources/META-INF/resources</code> directory, add a <code>reactive-fruits.html</code> file with
the content from this
<a href="https://github.com/datastax/cassandra-quarkus/tree/master/quickstart/src/main/resources/META-INF/resources/reactive-fruits.html">reactive-fruits.html</a>
file in it.</p>
</div>
<div class="paragraph">
<p>You can now interact with your reactive REST service:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>start Quarkus with <code>mvn clean quarkus:dev</code></p>
</li>
<li>
<p>open a browser to <code><a href="http://localhost:8080/reactive-fruits.html" class="bare">http://localhost:8080/reactive-fruits.html</a></code></p>
</li>
<li>
<p>add new fruits to the list via the form</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="connection-health-check"><a class="anchor" href="#connection-health-check"></a>Connection Health Check</h2>
<div class="sectionbody">
<div class="paragraph">
<p>If you are using the <code>quarkus-smallrye-health</code> extension, <code>cassandra-quarkus</code> will automatically
add a readiness health check to validate the connection to the cluster.</p>
</div>
<div class="paragraph">
<p>So when you access the <code>/health/ready</code> endpoint of your application you will have information about
the connection validation status.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
This behavior can be disabled by setting the <code>quarkus.cassandra.health.enabled</code> property to
<code>false</code> in your <code>application.properties</code>.
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="metrics"><a class="anchor" href="#metrics"></a>Metrics</h2>
<div class="sectionbody">
<div class="paragraph">
<p>If you are using the <code>quarkus-smallrye-metrics</code> extension, <code>cassandra-quarkus</code> can provide metrics
about QuarkusCqlSession and Cassandra nodes.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
This behavior must first be enabled by setting the <code>quarkus.cassandra.metrics.enabled</code>
property to <code>true</code> in your <code>application.properties</code>.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>The next step that you need to do is set explicitly which metrics should be enabled.</p>
</div>
<div class="paragraph">
<p>The <code>quarkus.cassandra.metrics.session-enabled</code> and <code>quarkus.cassandra.metrics.node-enabled</code>
properties should be used for enabling metrics; the former should contain a list of session-level
metrics to enable, while the latter should contain a list of node-level metrics to enable. Both
properties accept a comma-separated list of valid metric names.</p>
</div>
<div class="paragraph">
<p>For example, to enable <code>session.connected-nodes</code>, <code>session.bytes-sent</code>, and
<code>node.pool.open-connections</code> you should add the following settings to your <code>application.properties</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="properties" class="language-properties hljs">quarkus.cassandra.metrics.enabled=true
quarkus.cassandra.metrics.session-enabled=connected-nodes,bytes-sent
quarkus.cassandra.metrics.node-enabled=pool.open-connections</code></pre>
</div>
</div>
<div class="paragraph">
<p>For the full list of available metrics, please refer to the
<a href="https://docs.datastax.com/en/developer/java-driver/latest/manual/core/configuration/reference/">driver settings reference</a>
and the <code>advanced.metrics</code> section.</p>
</div>
<div class="paragraph">
<p>When metrics are properly enabled and when you access the <code>/metrics</code> endpoint of your application,
you will see metric reports for all enabled metrics.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="building-a-native-executable"><a class="anchor" href="#building-a-native-executable"></a>Building a native executable</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You can use the Cassandra client in a native executable.</p>
</div>
<div class="paragraph">
<p>You can build a native executable with the <code>mvn clean package -Dnative</code> command.</p>
</div>
<div class="paragraph">
<p>Running it is as simple as executing <code>./target/quickstart-1.0.0-SNAPSHOT-runner</code>.</p>
</div>
<div class="paragraph">
<p>You can then point your browser to <code><a href="http://localhost:8080/fruits.html" class="bare">http://localhost:8080/fruits.html</a></code> and use your application.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="conclusion"><a class="anchor" href="#conclusion"></a>Conclusion</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Accessing a Cassandra database from a client application is easy with Quarkus and the Cassandra
extension, which provides configuration and native support for the DataStax Java driver for
Apache Cassandra.</p>
</div>
</div>
</div>
    </div>
  </div>
</div>

  </div>

  <div class="content project-footer">
  <div class="footer-section">
    <div class="logo-wrapper">
      <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_reverse.svg" class="project-logo" title="Quarkus"></a>
    </div>
  </div>
  <div class="grid-wrapper">
    <p class="grid__item width-3-12">Quarkus is open. All dependencies of this project are available under the <a href='https://www.apache.org/licenses/LICENSE-2.0' target='_blank'>Apache Software License 2.0</a> or compatible license.<br /><br />This website was built with <a href='https://jekyllrb.com/' target='_blank'>Jekyll</a>, is hosted on <a href='https://pages.github.com/' target='_blank'>Github Pages</a> and is completely open source. If you want to make it better, <a href='https://github.com/quarkusio/quarkusio.github.io' target='_blank'>fork the website</a> and show us what you’ve got.</p>

    
      <div class="width-1-12 project-links">
        <span>Navigation</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="/">Home</a></li>
          
            <li><a href="/guides">Guides</a></li>
          
            <li><a href="/community/#contributing">Contribute</a></li>
          
            <li><a href="/faq">FAQ</a></li>
          
            <li><a href="/get-started">Get Started</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Contribute</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://twitter.com/quarkusio">Follow us</a></li>
          
            <li><a href="https://github.com/quarkusio">GitHub</a></li>
          
            <li><a href="/security">Security&nbsp;policy</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Get Help</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://groups.google.com/forum/#!forum/quarkus-dev">Forums</a></li>
          
            <li><a href="https://quarkusio.zulipchat.com">Chatroom</a></li>
          
        </ul>
      </div>
    

    
      <div class="width-3-12 more-links">
        <span>Quarkus is made of community projects</span>
        <ul class="footer-links">
          
            <li><a href="https://vertx.io/" target="_blank">Eclipse Vert.x</a></li>
          
            <li><a href="https://microprofile.io" target="_blank">Eclipse MicroProfile</a></li>
          
            <li><a href="https://hibernate.org" target="_blank">Hibernate</a></li>
          
            <li><a href="https://netty.io" target="_blank">Netty</a></li>
          
            <li><a href="https://resteasy.github.io" target="_blank">RESTEasy</a></li>
          
            <li><a href="https://camel.apache.org" target="_blank">Apache Camel</a></li>
          
            <li><a href="https://code.quarkus.io/" target="_blank">And many more...</a></li>
          
        </ul>
      </div>
    
  </div>
</div>
  <div class="content redhat-footer">
  <div class="grid-wrapper">
    <span class="licence">
      <i class="fab fa-creative-commons"></i><i class="fab fa-creative-commons-by"></i> <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC by 3.0</a> | <a href="https://www.redhat.com/en/about/privacy-policy">Privacy Policy</a>
    </span>
    <span class="redhat">
      Sponsored by
    </span>
    <span class="redhat-logo">
      <a href="https://www.redhat.com/" target="_blank"><img src="/assets/images/redhat_reversed.svg"></a>
    </span>
  </div>
</div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script>
  <script type="text/javascript" src="/assets/javascript/mobile-nav.js"></script>
  <script type="text/javascript" src="/assets/javascript/scroll-down.js"></script>
  <script src="/assets/javascript/satellite.js" type="text/javascript"></script>
  <script src="https://quarkus.io/guides/javascript/config.js" type="text/javascript"></script>
  <script src="/assets/javascript/search-filter.js" type="text/javascript"></script>
  <script src="/assets/javascript/back-to-top.js" type="text/javascript"></script>
</body>

</html>
